package uk.ac.imperial.doc.pctmc.charts;

import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.block.BlockBorder;
import org.jfree.chart.plot.DefaultDrawingSupplier;
import org.jfree.chart.plot.DrawingSupplier;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.GrayPaintScale;
import org.jfree.chart.renderer.xy.DeviationRenderer;
import org.jfree.chart.renderer.xy.XYBlockRenderer;
import org.jfree.chart.title.PaintScaleLegend;
import org.jfree.data.xy.XYDataset;
import org.jfree.data.xy.XYZDataset;
import org.jfree.ui.RectangleEdge;
import org.jfree.ui.RectangleInsets;
import org.jfree.ui.RefineryUtilities;
import uk.ac.imperial.doc.pctmc.utils.PCTMCOptions;

import javax.swing.*;
import java.awt.*;
import java.util.HashMap;
import java.util.Map;

public class PCTMCChartUtilities {

    public static boolean jogl = false;
	private static double lastx = 0, lasty = 0;

	private static Map<String, JFrame> windows = new HashMap<String, JFrame>();
	private static Map<String, JTabbedPane> tabs = new HashMap<String, JTabbedPane>();

    public static void nextBatch() {
		lasty = 0;
		lastx += 0.1;
	}

	public static void drawBlockChart(XYZDataset dataset, String xlabel,
			String ylabel, String zlabel, double dx, double dy, double minz,
			double maxz, String chartTitle, String windowTitle) {
		if (!PCTMCOptions.gui)
			return;
		NumberAxis xAxis = new NumberAxis(xlabel);
		xAxis.setAutoRangeIncludesZero(false);
		NumberAxis yAxis = new NumberAxis(ylabel);

		yAxis.setAutoRangeIncludesZero(false);
		XYBlockRenderer renderer = new XYBlockRenderer();
		if (minz == maxz)
			return;
		GrayPaintScale scale = new GrayPaintScale(minz, maxz);
		renderer.setPaintScale(scale);
		renderer.setBlockWidth(dx);
		renderer.setBlockHeight(dy);

		XYPlot plot = new XYPlot(dataset, xAxis, yAxis, renderer);
		plot.setBackgroundPaint(Color.DARK_GRAY);

		JFreeChart chart = new JFreeChart(chartTitle, plot);
		chart.removeLegend();

		NumberAxis scaleAxis = new NumberAxis("");// zlabel);
		scaleAxis.setRange(minz, maxz);

		PaintScaleLegend legend = new PaintScaleLegend(scale, scaleAxis);

		legend.setFrame(new BlockBorder(Color.GRAY));
		legend.setPadding(new RectangleInsets(5, 5, 5, 5));
		legend.setMargin(new RectangleInsets(4, 6, 40, 6));
		legend.setPosition(RectangleEdge.RIGHT);

		chart.addSubtitle(legend);

		chart.setBackgroundPaint(Color.white);

		ChartPanel chartPanel = new ChartPanel(chart);

		chartPanel.setMouseZoomable(true, false);
		chartPanel.setDoubleBuffered(true);

		final JFrame frame = new JFrame(windowTitle);

		frame.setPreferredSize(new java.awt.Dimension(600, 500));
		frame.setContentPane(chartPanel);
		frame.pack();
		frame.setVisible(true);

		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

		RefineryUtilities.positionFrameOnScreen(frame, lastx, lasty);
		lastx += 0.05;
		lasty += 0.05;
	}

	public static void setWindow(String windowTitle) {
		if (!PCTMCOptions.gui)
			return;
		String mainClass = "";// System.getenv("JAVA_MAIN_CLASS");
		JFrame frame;
		frame = new JFrame(mainClass + " " + windowTitle);
		JTabbedPane tab = new JTabbedPane();
		frame.setPreferredSize(new java.awt.Dimension(600, 480));

		frame.setContentPane(tab);
		frame.pack();
		frame.setVisible(true);

		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

		windows.put(windowTitle, frame);
		tabs.put(windowTitle, tab);
	}

	public static JFrame getWindow(String title) {
		return windows.get(title);
	}

	public static void addChart(Component component, String tabTitle, String windowTitle) {
		if (!PCTMCOptions.gui)
			return;
		JTabbedPane tab;
		if (!windows.containsKey(windowTitle))
			setWindow(windowTitle);
		tab = tabs.get(windowTitle);
		tab.addTab(tabTitle, component);
		windows.get(windowTitle).setSize(new java.awt.Dimension(600, 500));

	}

	public static void drawChart(XYDataset dataset, String xlabel,
			String ylabel, String chartTitle, String windowTitle) {
		if (!PCTMCOptions.gui)
			return;

		
		JTabbedPane tab;
		if (!windows.containsKey(windowTitle))
			setWindow(windowTitle);
		tab = tabs.get(windowTitle);
		

		JFreeChart chart = ChartFactory.createXYLineChart(null, // chart //
				// title
				xlabel, // x axis label
				ylabel, // y axis label
				dataset, // data
				PlotOrientation.VERTICAL, true, // include legend
				true, // tooltips
				false // urls
				);

		ChartPanel chartPanel = new ChartPanel(chart);
		chartPanel.setMouseZoomable(true, false);
		chartPanel.setDoubleBuffered(true);
		tab.addTab(chartTitle, chartPanel);
		

		// RefineryUtilities.positionFrameOnScreen(frame, lastx, lasty);
		// lastx += 0.05;
		// lasty += 0.05;
	}

	public static void drawDeviationChart(XYDataset dataset, String xlabel,
			String ylabel, String chartTitle, String windowTitle) {
		if (!PCTMCOptions.gui)
			return;

		JTabbedPane tab;
		if (!windows.containsKey(windowTitle))
			setWindow(windowTitle);
		tab = tabs.get(windowTitle);
		
		JFreeChart chart = ChartFactory.createXYLineChart(null, // chart //
				// title
				xlabel, // x axis label
				ylabel, // y axis label
				dataset, // data
				PlotOrientation.VERTICAL, true, // include legend
				true, // tooltips
				false // urls
				);

        chart.setBackgroundPaint(Color.white);
        
        // get a reference to the plot for further customisation...
        XYPlot plot = (XYPlot) chart.getPlot();
        plot.setBackgroundPaint(Color.lightGray);
        plot.setAxisOffset(new RectangleInsets(5.0, 5.0, 5.0, 5.0));
        plot.setDomainGridlinePaint(Color.white);
        plot.setRangeGridlinePaint(Color.white);

        
        DeviationRenderer renderer = new DeviationRenderer(true, false);
        
        Paint[] color = DefaultDrawingSupplier.DEFAULT_PAINT_SEQUENCE;
        for (int i=0; i< dataset.getSeriesCount(); i++)
        {
        	Color col = (Color)color[i];
	        renderer.setSeriesPaint(i, col);
	        col = col.brighter().brighter();
	        renderer.setSeriesFillPaint(i, new Color(col.getRed(), col.getGreen(), col.getBlue(),255));
        }
        plot.setRenderer(renderer);
                
		ChartPanel chartPanel = new ChartPanel(chart);
		chartPanel.setMouseZoomable(true, false);
		chartPanel.setDoubleBuffered(true);
		tab.addTab("", chartPanel);

		// RefineryUtilities.positionFrameOnScreen(frame, lastx, lasty);
		// lastx += 0.05;
		// lasty += 0.05;
	}
	
	public static void drawChartPairs(XYDataset dataset, String xlabel,
			String ylabel, String chartTitle, String windowTitle) {
		if (!PCTMCOptions.gui)
			return;
		
		JFreeChart chart = ChartFactory.createXYLineChart(null, // chart //
				// title
				xlabel, // x axis label
				ylabel, // y axis label
				dataset, // data
				PlotOrientation.VERTICAL, true, // include legend
				true, // tooltips
				false // urls
				);

		Paint[] colors = DefaultDrawingSupplier.DEFAULT_PAINT_SEQUENCE;
		Paint[] newColors = new Paint[colors.length * 2];

		for (int i = 0; i < colors.length; i++) {
			newColors[2 * i] = colors[i];
			newColors[2 * i + 1] = colors[i];
		}

		DrawingSupplier newSupplier = new DefaultDrawingSupplier(newColors,
				DefaultDrawingSupplier.DEFAULT_OUTLINE_PAINT_SEQUENCE,
				DefaultDrawingSupplier.DEFAULT_STROKE_SEQUENCE,
				DefaultDrawingSupplier.DEFAULT_OUTLINE_STROKE_SEQUENCE,
				DefaultDrawingSupplier.DEFAULT_SHAPE_SEQUENCE);

		chart.getPlot().setDrawingSupplier(newSupplier);

		final JFrame frame = new JFrame(windowTitle);
		ChartPanel chartPanel = new ChartPanel(chart);

		chartPanel.setMouseZoomable(true, false);
		chartPanel.setDoubleBuffered(true);
		frame.setPreferredSize(new java.awt.Dimension(600, 400));
		frame.setContentPane(chartPanel);
		frame.pack();
		frame.setVisible(true);

		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

		RefineryUtilities.positionFrameOnScreen(frame, lastx, lasty);
		lastx += 0.05;
		lasty += 0.05;
	}

}
